import poplib
import mesgparser
import email.FeedParser
import hall
from bsddb import db
import time

uidlPool = None

def fetchServer (host, user, password, saveTime):
    global uidlPool

    server = poplib.POP3_SSL(host)
    server.user(user)
    server.pass_(password)

    numMessages = len(server.list()[1]);
    uidlList = server.uidl()[1]
    toDelete = []
    
    if (len(uidlList) != numMessages):
        print 'Unmatched uidlList'
        return None
    
    for i in range(numMessages):
        now = time.time()        

        # Detect UIDL
        key = '%s.%s@%s' % (uidlList[i], user, host)
        ret = uidlPool.get(key)
        # Handle the old message
        if (ret):
            print '%d, %s  recevied before, skip' % ((i + 1), key)            
            fetchTime = int(ret)
            if (fetchTime + saveTime < now):
                print '%s is %d secs ago, delete' % (key, now - fetchTime)
                toDelete.append(i + 1)
            continue
        
        # This is a new message        
        print 'Receving new message %d, %s' % ((i + 1), key)
        data = server.retr(i+1)[1]        
        parser = email.FeedParser.FeedParser()    
        for line in data:
            parser.feed(line + '\r\n')            
	try:            
            mesg = mesgparser.convMessage(parser.close())
            hall.contentMan.addMessage(mesg)
            uidlPool.put(key, '%d' % now)
            if (saveTime <= 0):
                toDelete.append(i + 1)                
	except:
            print 'Failed to fetch message, ignore'

    # Delete old mails
    for num in toDelete:
        print 'Delete old mail %d' % num
        server.dele(num)        
        
    server.quit()
    
if __name__ == '__main__':
    uidlPool = db.DB()
    uidlPool.open(hall.dbconf['UIDL.POOL'], dbtype = db.DB_BTREE, flags = db.DB_CREATE)    
    
    for desc in hall.pop3conf:
        host, user, password, saveTime = desc
        print 'Fetching %s@%s' % (user, host)
        fetchServer(host, user, password, saveTime)

